home *** CD-ROM | disk | FTP | other *** search
- #include <Events.h>
- #include <Resources.h>
- #include <Memory.h>
- #include <ToolUtils.h>
- #include <Gestalt.h>
- #include <Errors.h>
- #include <StringCompare.h>
- #include <Sound.h>
-
- #include "RSO.h"
-
- // some sane defaults in case we can't find our prefs.
- JiverGlobals gJiverGlobs = {
- 1, // on by default
- "\pJive"
- };
-
- pascal short (*gOldSystemEvent)(EventRecord *ep);
- pascal short JiverSystemEvent(EventRecord *ep);
-
- pascal void (*gOldModalDialog)(ModalFilterUPP modalFilter, DialogItemIndex *itemHit);
- pascal void JiverModalDialog(ModalFilterUPP modalFilter, DialogItemIndex *itemHit);
-
- enum {
- uppSystemEventProcInfo = kPascalStackBased | RESULT_SIZE(kTwoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode)
- };
- enum {
- uppModalDialogProcInfo = kPascalStackBased | RESULT_SIZE(kNoByteCode) | STACK_ROUTINE_PARAMETER(1, kFourByteCode) | STACK_ROUTINE_PARAMETER(2, kFourByteCode)
- };
-
- SelectorFunctionUPP ourGestaltUPP;
-
- static pascal OSErr JiverGestalt(OSType selector, long *_response);
-
- #ifdef powerc
- // for Metrowerks' linker, this defines the interface for main().
- ProcInfoType __procinfo = kCStackBased | RESULT_SIZE(kNoByteCode);
- #endif
-
- void main(void)
- {
- long oldA4;
- THz oldZone;
- JiverGlobals **bgh;
- UniversalProcPtr newSystemEventAddress;
- UniversalProcPtr newModalDialogAddress;
-
- // Set up A4, so we can access our globals.
- oldA4 = SetCurrentA4();
-
- // Set the current zone to the system zone. In the 680x0 case, this
- // is not necessary, but it's not a bad idea and it keeps us out of
- // trouble when traps that we don't expect to have side effects
- // unexpectedlty allocate memory from the current zone. One example
- // of this is the NewRoutineDescriptor routine.
- oldZone = GetZone();
- SetZone(SystemZone());
-
- // OK, we're relying on gestalt, so we have to be sure that it's
- // implemented. We do this by checking to see that Gestalt's trap
- // address is different from the address of unimplemented traps.
- if (GetOSTrapAddress(kGestaltTrapNumber) == UnimplementedTrapAddress) goto initFailed;
-
- ourGestaltUPP = NewSelectorFunctionProc(JiverGestalt);
- if (ourGestaltUPP == 0) goto initFailed;
-
- newSystemEventAddress = NewRoutineDescriptor((ProcPtr) &JiverSystemEvent,uppSystemEventProcInfo,GetCurrentArchitecture());
- if (newSystemEventAddress == 0) goto initFailed;
-
- newModalDialogAddress = NewRoutineDescriptor((ProcPtr) &JiverModalDialog,uppModalDialogProcInfo,GetCurrentArchitecture());
- if (newModalDialogAddress == 0) goto initFailed;
-
- // now install our gestalt selector, which sets up a mechanism for our control panel
- // to talk to us and at the same time makes sure we're not loading twice.
- if (NewGestalt(kDTS_Signature, ourGestaltUPP) != noErr) goto initFailed;
-
- // At this point, we have tested for any failure conditions, and nothing has gone wrong.
- // So now is the time to detach our code, patch our traps, and settle in.
- DetachResource(GetResource('INIT', -4048));
-
- // Remember the old implementation of SystemEvent
- gOldSystemEvent = (void *) GetToolTrapAddress(kSystemEventTrapNumber);
- gOldModalDialog = (void *) GetToolTrapAddress(kModalDialogTrapNumber);
-
- // Patch ourselves in.
- SetToolTrapAddress(newSystemEventAddress, kSystemEventTrapNumber);
- SetToolTrapAddress(newModalDialogAddress, kModalDialogTrapNumber);
-
- bgh = (JiverGlobals **)Get1Resource('pref', -4048);
- if (bgh != 0 && GetHandleSize((Handle)bgh) == sizeof(gJiverGlobs)) {
- gJiverGlobs = **bgh;
- }
-
- initFailed:
- // Restore the old zone again
- SetZone(oldZone);
-
- // And restore the value of A4 on the way out.
- SetA4(oldA4);
- }
-
- static pascal OSErr JiverGestalt(OSType selector, long *response) {
- long oldA4;
- OSErr err = noErr;
-
- // Set up A4, so we can access our globals.
- oldA4 = SetCurrentA4();
-
- switch (selector) {
- case kGestaltGetInitGlobals:
- *response = (long)&gJiverGlobs;
- break;
- case kDTS_Signature:
- *response = (long)ourGestaltUPP;
- break;
- case gestaltVersion:
- *response = 0x0100; // version 1.0 Gestalt interface for Jiver.
- break;
- default:
- err = gestaltUnknownErr;
- break;
- }
-
- // Restore the value of A4 on the way out.
- SetA4(oldA4);
- return err;
- }
-
- #if 0 // This is used for ReturnStillOpens
- pascal short JiverSystemEvent(EventRecord *ep)
- {
- // Set up A4, so we can access our globals.
- long oldA4;
- short result;
-
- oldA4 = SetCurrentA4();
-
- // Check for keyDown events, and change return to command-O
- if (gJiverGlobs.JiverOn) {
- if (ep->what == keyDown && ep->modifiers == btnState && (ep->message & 0xFF) == '\r') {
- if (*(long *)0x910 == *(long *)0x2E0) {
- ep->message = 'o' + (0xFFFFFF00 & ep->message);
- ep->modifiers |= cmdKey;
- }
- }
- }
-
- // Call the old SystemEvent:
- #ifndef powerc
- result = gOldSystemEvent(str);
- #else
- result = CallUniversalProc((UniversalProcPtr)gOldSystemEvent, uppSystemEventProcInfo, ep);
- #endif
- // And restore the value of A4 on the way out.
- SetA4(oldA4);
- return result;
- }
- #else
- WindowPtr gLastMD;
- pascal void JiverModalDialog(ModalFilterUPP modalFilter, DialogItemIndex *itemHit) {
- // Set up A4, so we can access our globals.
- long oldA4;
- short result;
-
- oldA4 = SetCurrentA4();
-
- gLastMD = FrontWindow();
-
- // Call the old ModalDialog:
- #ifndef powerc
- result = gOldModalDialog(str);
- #else
- result = CallUniversalProc((UniversalProcPtr)gOldModalDialog, uppModalDialogProcInfo, modalFilter, itemHit);
- #endif
-
- // And restore the value of A4 on the way out.
- SetA4(oldA4);
- }
-
- static void LookForDefaultButton(void) {
- WindowPtr wp = FrontWindow();
- WindowRecord * wrp = (WindowRecord *)wp;
- DialogItemType itemType;
- Handle item;
- Rect r;
-
- r.top = 0;
- r.bottom = 0;
- r.left = 0;
- r.right = 0;
-
- if (wp == gLastMD && wrp->controlList) {
- DialogRecord *drp = (DialogRecord *)wrp;
-
- GetDialogItem(wp, drp->aDefItem, &itemType, &item, &r);
- if (itemType != btnCtrl && itemType != resCtrl && itemType != ctrlItem) {
- r.top = 0;
- r.bottom = 0;
- r.left = 0;
- r.right = 0;
- } else {
- GrafPtr gp;
- GetPort(&gp);
- SetPort(wp);
- LocalToGlobal(0 + (Point *)&r);
- LocalToGlobal(1 + (Point *)&r);
- SetPort(gp);
- }
- }
-
- *(Rect *)0x40 = r;
- }
-
- pascal short JiverSystemEvent(EventRecord *ep)
- {
- // Set up A4, so we can access our globals.
- long oldA4;
- short result;
-
- oldA4 = SetCurrentA4();
-
- // Call the old SystemEvent:
- #ifndef powerc
- result = gOldSystemEvent(str);
- #else
- result = CallUniversalProc((UniversalProcPtr)gOldSystemEvent, uppSystemEventProcInfo, ep);
- #endif
-
- LookForDefaultButton();
-
- // And restore the value of A4 on the way out.
- SetA4(oldA4);
- return result;
- }
- #endif